home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Whiteline: delta
/
whiteline CD Series - delta.iso
/
progtool
/
c
/
dev_lib1
/
src
/
dev_lib.c
next >
Wrap
C/C++ Source or Header
|
1995-11-25
|
27KB
|
1,342 lines
/*
* Project : Device Library Version 0.20beta
* Module : dev_lib.c
* Author : Jan Kriesten
* Date : 07.05.1995
*
* Description: main routines to install/deinstall devices
*
* Tabsize 4
*/
/*-----------------------------*/
/*--- includes ---*/
/*-----------------------------*/
#include <import.h>
#include <device.h>
#include "dev_misc.h"
#include "types.h"
#include "port.h"
#include <export.h>
/*-----------------------------*/
/*--- defines ---*/
/*-----------------------------*/
#define BMAPSTART 5
#define MAX_BLOCK 4096L
#define MAX_SPEEDS 25
/*-----------------------------*/
/*--- types ---*/
/*-----------------------------*/
typedef struct
{
/*
* Sichtbar für den User:
*/
DEV_LIST device; /* Liste der Device-Namen */
/*
* Sytemdaten:
*/
WORD bios; /* BIOS-Nr. des Devices */
WORD func_num; /* "normierte" Bconmap-Zugriffsnummer */
BYTE *dopen; /* Name des Devices für Fopen( ) */
/*
* Daten zur Verwaltung des Devices:
*/
BOOLEAN is_open; /* TRUE, falls Device geöffnet */
WORD dhandle; /* handle, falls mit Fopen( ) geöffnet */
WORD curr_pos; /* aktulle Position im Puffer */
WORD num_read; /* Anzahl der eingelesenen Zeichen */
BYTE *buf; /* Zeiger Blockdevice-Puffer */
LONG *speeds; /* Liste der einstellbaren DTE-speeds */
CHAN_INFO *chan_info; /* Struktur unter FastSeriell */
MAPTAB *func_map; /* Tabelle der einzelnen Funktionen */
WORD oldIBufSize,
oldOBufSize;
BYTE *oldIBufPtr,
*oldOBufPtr;
LONG ioctrlmap[6]; /* Index der möglichen Fcntl-Funktionen */
} DEVICES;
typedef union
{
UWORD word;
struct
{
UWORD bit7_15 : 9;
UWORD bit5_6 : 2;
UWORD bit3_4 : 2;
UWORD bit2 : 1;
UWORD bit1 : 1;
UWORD bit0 : 1;
} bits;
} UCR;
/*-----------------------------*/
/*--- variables ---*/
/*-----------------------------*/
LOCAL UWORD atari,
tos,
MiNT;
LOCAL FSER_INFO *fser;
LOCAL RSVF_DEV *rsvf;
LOCAL BOOLEAN has_bconmap,
has_drv_u;
LOCAL BYTE *d_name[] = {
"Modem 1",
"Modem 2",
"Serial 1",
"Serial 2",
"Midi"
},
*d_open[] = {
"MODEM1",
"MODEM2",
"SERIAL1",
"SERIAL2",
};
LOCAL LONG speeds[] = {
19200L,
9600L,
4800L,
3600L,
2400L,
2000L,
1800L,
1200L,
600L,
300L,
200L,
150L,
134L,
110L,
75L,
50L,
-1L
};
LOCAL LONG midi_speeds[] = { 31250, -1 };
LOCAL DEVICES *devices;
LOCAL LONG cntrls[4];
LOCAL VOID (*pause_1)( VOID );
EXTERN VOID (*pause_2)( VOID );
/*--- prototypes ---*/
LOCAL BOOLEAN InitStdDevices ( MAPTAB *maps, BOOLEAN has_bconmap, WORD num_devices );
LOCAL BOOLEAN InitRSVFDevices ( MAPTAB *maps, RSVF_DEV *dev );
LOCAL BOOLEAN CreateSpeedlist ( DEVICES *dev );
LOCAL VOID GetFcntlSpeeds ( DEVICES *dev );
LOCAL VOID GetFserSpeeds ( DEVICES *dev );
LOCAL VOID FreeSpeedlist ( DEVICES *dev );
LOCAL VOID SetDevFunctions ( DEVICES *dev );
LOCAL VOID SetPortProtokoll( DEVICES *dev );
LOCAL BOOLEAN DevicePickup ( DEVICES *dev );
LOCAL BOOLEAN DeviceSendBlock ( DEVICES *dev, BYTE *block, LONG len, BOOLEAN tst_dcd );
/*-----------------------------*/
/*--- global functions ---*/
/*-----------------------------*/
/*-------------------------------------------------------------------*/
GLOBAL DEV_LIST *InitDevices( VOID *timerelease1, VOID *timerelease2 )
{
/*
* Initialisiert alle vorhandenen Ports/Devices.
*/
WORD num_devices;
BOOLEAN mega;
MAPTAB *maps;
devices = NULL;
tos = get_tos( );
has_drv_u = has_drive_u( );
has_bconmap = (Bconmap( 0 )==0L);
pause_1 = timerelease1;
pause_2 = timerelease2;
atari = getcookie( '_MCH', cntrls ) ? (UWORD) (cntrls[0]>>16) : 0;
mega = (UWORD) cntrls[0] ? TRUE : FALSE;
fser = getcookie( 'FSER', cntrls ) ? (FSER_INFO *) cntrls[0] : NULL;
MiNT = getcookie( 'MiNT', cntrls ) ? (WORD) cntrls[0] : 0;
rsvf = getcookie( 'RSVF', cntrls ) ? (RSVF_DEV *) cntrls[0] : NULL;
/*
* Set MiNT process execution domain (to let Fread, Fwrite
* behave as stated in the terminal settings):
*/
if( MiNT && !rsvf && !fser )
Pdomain( 1 );
if( has_bconmap )
{
BCONMAP *bmap = (BCONMAP *) Bconmap( -2 );
maps = bmap->maptab;
num_devices = bmap->maptabsize;
if( !maps )
has_bconmap = FALSE;
}
else
maps = NULL;
switch( atari )
{
case 0:
case 3:
num_devices = 1;
break;
case 1:
num_devices = mega ? 3 : 1;
break;
case 2:
num_devices = 4;
break;
}
if( !InitStdDevices( maps, has_bconmap, num_devices ) )
return( NULL );
if( rsvf && !InitRSVFDevices( maps, rsvf ) )
return( NULL );
return( (devices) ? &(devices->device) : NULL );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID TermDevices( VOID )
{
/*
* Gibt den Speicher der Device-Liste wieder frei:
*/
DEVICES *dwalk;
for( dwalk=devices; dwalk; dwalk=devices )
{
CloseDevice( (DEV_LIST *) dwalk );
devices = (DEVICES *) dwalk->device.next;
free( dwalk );
}
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN OpenDevice( DEV_LIST *port )
{
/*
* Öffnet port und stellt alle entsprechenden Funktionen zusammen.
*/
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->is_open )
return( FALSE );
/*
* Erst den Standard-Aux umsetzen:
*/
if( has_bconmap && dev->bios>5 )
Bconmap( dev->bios );
/*
* Bei FastSerial keine Blockdevice-Routinen benutzen:
*/
if( fser && (dev->bios==1 || dev->bios>5) )
{
CHAN_INFO *tst;
tst = (CHAN_INFO *) Rsconf( -3, -3, -1, -1, -1, -1 );
if( tst->task>0 )
return( FALSE );
dev->chan_info = tst;
dev->is_open = TRUE;
}
/*
* Testen, ob es sich um ein Block-Device handelt:
*/
if( !dev->is_open && dev->dopen )
{
BYTE path[64];
LONG rc;
strcpy( path, "U:\\DEV\\" );
strcpy( path+7, dev->dopen );
if( (rc=Fopen( path, FO_RW|O_NDELAY ))>=0 )
{
dev->dhandle = (WORD) rc;
dev->is_open = TRUE;
if( (dev->buf=(BYTE *) malloc( MAX_BLOCK * sizeof( BYTE ) ))==NULL )
{
CloseDevice( port );
return( FALSE );
}
}
/*
* Falls -36 (EACCDN) zurückgegeben wird, so wurde das Device
* schon von einer anderen Applikation geöffnet.
*/
else if( rc==-36L )
return( FALSE );
}
dev->is_open = TRUE;
SetDevFunctions( dev );
SetPortProtokoll( dev );
if( !CreateSpeedlist( dev ) )
CloseDevice( port );
else
StartReceiver( port );
return( dev->is_open );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID CloseDevice( DEV_LIST *port )
{
/*
* Schließt port und gibt den Speicher wieder frei
*/
DEVICES *dev;
dev = (DEVICES *) port;
if( !dev->is_open )
return;
if( dev->dhandle>=0 )
{
Fclose( dev->dhandle );
dev->dhandle = -1;
}
if( dev->buf )
{
free( dev->buf );
dev->buf = NULL;
}
if( dev->oldIBufPtr )
{
IOREC *iorec;
BYTE *b;
iorec = dev->func_map->iorec;
b = iorec->ibuf;
SetIorec( iorec, dev->oldIBufPtr, dev->oldIBufSize );
(MiNT) ? Mfree( b ) : free( b );
dev->oldIBufPtr = NULL;
}
if( dev->oldOBufPtr )
{
IOREC *iorec;
BYTE *b;
iorec = dev->func_map->iorec;
++iorec;
b = iorec->ibuf;
SetIorec( iorec, dev->oldOBufPtr, dev->oldOBufSize );
(MiNT) ? Mfree( b ) : free( b );
dev->oldOBufPtr = NULL;
}
FreeSpeedlist( dev );
dev->is_open = FALSE;
return;
}
/*-------------------------------------------------------------------*/
GLOBAL WORD GetBiosNr( DEV_LIST *dev )
{
return( ((DEVICES *) dev)->bios );
}
/*-------------------------------------------------------------------*/
GLOBAL LONG *GetSpeedList( DEV_LIST *dev )
{
return( ((DEVICES *) dev)->speeds );
}
/*-------------------------------------------------------------------*/
GLOBAL LONG SetDTESpeed( DEV_LIST *port, LONG speed )
{
DEVICES *dev;
dev = (DEVICES *) port;
/*
* Erst den Standard-Aux umsetzen:
*/
if( has_bconmap && dev->bios>5 )
Bconmap( dev->bios );
if( dev->dhandle>=0 )
{
cntrls[0] = speed;
if( !Fcntl( dev->dhandle, cntrls, TIOCIBAUD ) )
dev->device.curr_dte = speed;
}
else if( dev->bios==3 )
{
return( dev->device.curr_dte );
}
else if( fser )
{
WORD i=0;
BAUD_INFO *help;
help = (fser->baud_table_flag) ? dev->chan_info->alt_baud_table : dev->chan_info->baud_table;
while( help->baudrate )
{
if( help->baudrate==speed )
break;
i++, help++;
}
if( help->baudrate>0 )
{
Rsconf( i, -1, -1, -1, -1, -1 );
dev->device.curr_dte = speed;
}
}
else
{
WORD i=0;
LONG *help=dev->speeds;
while( *help>0 )
{
if( *help==speed )
break;
i++, help++;
}
if( *help>0 )
{
Rsconf( i, -1, -1, -1, -1, -1 );
dev->device.curr_dte = speed;
}
}
return( dev->device.curr_dte );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID StartReceiver( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
Fcntl( dev->dhandle, NULL, TIOCSTART );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID StopReceiver( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
Fcntl( dev->dhandle, NULL, TIOCSTOP );
}
/*-------------------------------------------------------------------*/
GLOBAL WORD SetTxBuffer( DEV_LIST *port, WORD size )
{
DEVICES *dev;
IOREC *iorec;
BYTE *mem, *b=NULL;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
cntrls[0] = cntrls[1] = cntrls[2] = -1L;
cntrls[3] = (LONG) size;
if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
return( (WORD) cntrls[3] );
}
if( (mem=(BYTE *) (MiNT ? Mxalloc( size, 0x23 ) : malloc( size )))==NULL )
return( -1 );
iorec = dev->func_map->iorec;
++iorec;
if( !dev->oldOBufPtr )
{
dev->oldOBufSize = iorec->ibufsiz;
dev->oldOBufPtr = iorec->ibuf;
}
else
b = iorec->ibuf;
SetIorec( iorec, mem, size );
if( b )
{
(MiNT) ? Mfree( b ) : free( b );
}
return( size );
}
/*-------------------------------------------------------------------*/
GLOBAL WORD GetTxBuffer( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
cntrls[0] = cntrls[1] = cntrls[2] = cntrls[3] = -1L;
if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
return( (WORD) cntrls[3] );
}
return( -1 );
}
/*-------------------------------------------------------------------*/
GLOBAL WORD SetRxBuffer( DEV_LIST *port, WORD size )
{
DEVICES *dev;
IOREC *iorec;
BYTE *mem, *b=NULL;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
cntrls[0] = (LONG) size;
cntrls[1] = (LONG) (size >> 2);
cntrls[2] = (LONG) ((size + size + size) >> 2);
cntrls[3] = -1L;
if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
return( (WORD) cntrls[0] );
}
if( (mem=(BYTE *) (MiNT ? Mxalloc( size, 0x23 ) : malloc( size )))==NULL )
return( -1 );
iorec = dev->func_map->iorec;
if( !dev->oldIBufPtr )
{
dev->oldIBufSize = iorec->ibufsiz;
dev->oldIBufPtr = iorec->ibuf;
}
else
b = iorec->ibuf;
SetIorec( iorec, mem, size );
if( b )
{
(MiNT) ? Mfree( b ) : free( b );
}
return( size );
}
/*-------------------------------------------------------------------*/
GLOBAL WORD GetRxBuffer( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
cntrls[0] = cntrls[1] = cntrls[2] = cntrls[3] = -1L;
if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
return( (WORD) cntrls[0] );
}
return( -1 );
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN PortSendByte( DEV_LIST *port, BYTE c )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
return( DeviceSendBlock( dev, &c, 1L, FALSE ) );
else if( dev->bios>=0 )
{
while( !Bcostat( dev->bios==3 ? 4 : dev->bios ) )
{
if( pause_1 )
pause_1( );
}
Bconout( dev->bios, c );
return( TRUE );
}
return( FALSE );
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN PortSendBlock( DEV_LIST *port, BYTE *block, LONG len, BOOLEAN tst_dcd )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
return( DeviceSendBlock( dev, block, len, tst_dcd ) );
else if( dev->bios==3 )
{
Midiws( (WORD) len-1, block );
return( TRUE );
}
else if( dev->bios>=0 )
return( SendBlock( dev, block, len, tst_dcd ) );
return( FALSE );
}
/*-------------------------------------------------------------------*/
GLOBAL WORD PortGetByte( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 || dev->bios>=0 )
{
while( !CharAvailable( port ) )
{
if( !IsCarrier( port ) )
return( -1 );
if( pause_1 )
pause_1( );
}
return( (dev->dhandle>=0 ? dev->buf[dev->curr_pos++] : (WORD) Bconin( dev->bios )) & 0xff );
}
return( -1 );
}
/*-------------------------------------------------------------------*/
GLOBAL WORD PortPeekByte( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
if( CharAvailable( port ) )
return( dev->buf[dev->curr_pos] & 0xff );
}
else if( dev->bios>=0 );
{
IOREC *iorec;
iorec = dev->func_map->iorec;
if( iorec->ibufhd!=iorec->ibuftl )
{
WORD pos=iorec->ibufhd;
if( pos>=iorec->ibufsiz )
pos = 0;
return( iorec->ibuf[pos] & 0xff );
}
}
return( -1 );
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN OutIsEmpty( DEV_LIST *port )
{
DEVICES *dev;
IOREC *iorec;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
if( !Fcntl( dev->dhandle, cntrls, TIONOTSEND ) )
return( cntrls[0]==0L );
}
iorec = dev->func_map->iorec;
iorec++;
return( iorec->ibufhd==iorec->ibuftl );
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN WaitOutEmpty( DEV_LIST *port, BOOLEAN tst_dcd, UWORD wait )
{
ULONG time_to_wait;
if( wait )
time_to_wait = Calc200Hz( (ULONG) wait );
while( !OutIsEmpty( port ) )
{
if( (tst_dcd && !IsCarrier( port )) ||
(wait && time_to_wait<Get200Hz( )) )
{
ClearIOBuffer( port, IO_O_BUFFER );
return( FALSE );
}
if( pause_1 )
pause_1( );
}
return( TRUE );
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN CharAvailable( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
return( dev->num_read>dev->curr_pos || DevicePickup( dev ) );
else if( dev->bios>=0 )
return( Bconstat( dev->bios )<0L );
return( FALSE );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID ClearIOBuffer( DEV_LIST *port, LONG io )
{
DEVICES *dev;
IOREC *iorec;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
if( !Fcntl( dev->dhandle, io, TIOCFLUSH ) )
{
if( io!=IO_O_BUFFER )
{
dev->curr_pos = 0;
dev->num_read = -1;
StartReceiver( port );
}
return;
}
}
iorec = dev->func_map->iorec;
if( io!=IO_O_BUFFER )
{
/* Inbuffer löschen: */
iorec->ibuftl = iorec->ibufhd;
dev->curr_pos = 0;
dev->num_read = -1;
StartReceiver( port );
}
if( io!=IO_I_BUFFER )
{
/* Outbuffer löschen: */
iorec++;
iorec->ibufhd = iorec->ibuftl;
}
}
/*-------------------------------------------------------------------*/
GLOBAL VOID DtrOn( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 && dev->ioctrlmap[0] & TIOCM_DTR )
{
cntrls[0] = cntrls[1] = TIOCM_DTR;
Fcntl( dev->dhandle, cntrls, TIOCCTLSET );
}
else if( dev->func_num )
high_dtr( dev->func_num-1, dev->func_map );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID DtrOff( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 && dev->ioctrlmap[0] & TIOCM_DTR )
{
cntrls[0] = TIOCM_DTR;
cntrls[1] = 0;
Fcntl( dev->dhandle, cntrls, TIOCCTLSET );
}
else if( dev->func_num )
low_dtr( dev->func_num-1, dev->func_map );
}
/*-------------------------------------------------------------------*/
GLOBAL BOOLEAN IsCarrier( DEV_LIST *port )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 &&
dev->ioctrlmap[0] & TIOCM_CAR )
{
cntrls[0] = TIOCM_CAR;
Fcntl( dev->dhandle, cntrls, TIOCCTLGET );
return( (UWORD) cntrls[0] & TIOCM_CAR );
}
else
if( dev->func_num )
return( is_dcd( dev->func_num-1 ) );
return( TRUE );
}
/*-------------------------------------------------------------------*/
GLOBAL VOID PortParameter( DEV_LIST *port, UWORD flowctl, UWORD charlen, UWORD stopbits, UWORD parity )
{
DEVICES *dev;
dev = (DEVICES *) port;
if( dev->dhandle>=0 )
{
UWORD flags;
if( !Fcntl( dev->dhandle, &flags, TIOCGFLAGS ) )
{
flags &= ~(TF_STOPBITS|TF_CHARBITS|TF_FLAG);
flags |= (flowctl|charlen|stopbits|parity);
Fcntl( dev->dhandle, &flags, TIOCSFLAGS );
return;
}
}
if( dev->bios==1 || dev->bios>5 )
{
LONG flags;
UCR ucr;
if( has_bconmap && dev->bios>5 )
Bconmap( dev->bios );
flags = Rsconf( -1, -1, -1, -1, -1, -1 );
ucr.word = *((BYTE *) &flags);
ucr.word &= 0x0081;
if( parity )
{
ucr.bits.bit2 = 1;
if( parity==_EVENP )
ucr.bits.bit1 = 1;
}
ucr.bits.bit3_4 = stopbits;
ucr.bits.bit5_6 = charlen>>2;
Rsconf( -1, flowctl, ucr.word, -1, -1, -1 );
}
}
/*-----------------------------*/
/*--- local functions ---*/
/*-----------------------------*/
/*-------------------------------------------------------------------*/
LOCAL BOOLEAN InitStdDevices( MAPTAB *maps, BOOLEAN has_bconmap, WORD num_devices )
{
DEVICES *dptr, *dwalk=NULL;
WORD loop, i;
if( !has_bconmap || !num_devices )
num_devices = 1;
loop = (num_devices>4) ? 4 : num_devices;
for( i=1; i<=loop; i++ )
{
if( (dptr=(DEVICES *) calloc( 1, sizeof( DEVICES ) ))==NULL )
return( FALSE );
if( dwalk )
dwalk->device.next = (DEV_LIST *) dptr;
else
devices = dptr;
dwalk = dptr;
switch( i )
{
case 1:
if( atari!=3 || num_devices!=1 )
{
dwalk->bios = (has_bconmap) ? 6 : 1;
dwalk->func_num = 6 - BMAPSTART;
dwalk->device.name = d_name[0];
if( has_drv_u )
dwalk->dopen = d_open[0];
break;
}
case 2:
dwalk->bios = 7;
dwalk->func_num = 7 - BMAPSTART;
dwalk->device.name = d_name[1];
if( has_drv_u )
dwalk->dopen = d_open[1];
break;
case 3:
dwalk->bios = 8;
if( atari==1 )
{
dwalk->func_num = 9 - BMAPSTART;
dwalk->device.name = d_name[3];
if( has_drv_u )
dwalk->dopen = d_open[3];
}
else
{
dwalk->func_num = 8 - BMAPSTART;
dwalk->device.name = d_name[2];
if( has_drv_u )
dwalk->dopen = d_open[2];
}
break;
case 4:
dwalk->bios = 9;
dwalk->func_num = 9 - BMAPSTART;
dwalk->device.name = d_name[3];
if( has_drv_u )
dwalk->dopen = d_open[3];
break;
}
dwalk->dhandle = -1;
dwalk->num_read = -1;
if( has_bconmap )
dwalk->func_map = &maps[dwalk->bios-6];
else if( i==1 )
SetMapM1( &dwalk->func_map );
}
if( (dptr=(DEVICES *) calloc( 1, sizeof( DEVICES ) ))==NULL )
return( FALSE );
dwalk->device.next = (DEV_LIST *) dptr;
dptr->bios = 3;
dptr->device.name = d_name[4];
dptr->dhandle = -1;
dptr->num_read = -1;
SetMapMidi( &dptr->func_map );
return( TRUE );
}
/*-------------------------------------------------------------------*/
LOCAL BOOLEAN InitRSVFDevices( MAPTAB *maps, RSVF_DEV *dev )
{
DEVICES *dwalk;
while( dev->ptr )
{
if( !(dev->typ.device) )
{
dev = dev->ptr;
continue;
}
dwalk = devices;
while( dwalk )
{
if( (dwalk->bios==dev->bios_nr && strcmp( dev->ptr, "LAN" )) ||
(!strcmp( dev->ptr, "MIDI" ) && dwalk->bios==3) )
{
if( dwalk->bios==3 )
dwalk->bios = (dev->typ.bios) ? dev->bios_nr : 3;
break;
}
dwalk = (DEVICES *) dwalk->device.next;
}
if( !dwalk )
{
DEVICES *dptr;
if( (dptr=(DEVICES *) calloc( 1, sizeof( DEVICES ) ))==NULL )
return( FALSE );
dwalk = devices;
while( dwalk->device.next )
dwalk = (DEVICES *) dwalk->device.next;
dwalk->device.next = (DEV_LIST *) dptr;
dwalk = dptr;
dwalk->device.name = (BYTE *) dev->ptr;
dwalk->bios = (dev->typ.bios) ? dev->bios_nr : -1;
dwalk->dhandle = -1;
dwalk->num_read = -1;
dwalk->func_map = (dwalk->bios>5) ? &maps[dwalk->bios-6] : NULL;
}
dwalk->dopen = (BYTE *) dev->ptr;
dev++;
}
return( TRUE );
}
/*-------------------------------------------------------------------*/
LOCAL BOOLEAN CreateSpeedlist( DEVICES *dev )
{
if( (dev->speeds=(LONG *) calloc( MAX_SPEEDS, sizeof( LONG * ) ))==NULL )
return( FALSE );
if( dev->dhandle>=0 )
GetFcntlSpeeds( dev );
else if( dev->bios==3 ) /* Midi */
{
LONG *a_ptr, *b_ptr;
a_ptr = midi_speeds;
b_ptr = dev->speeds;
while( *a_ptr>0 )
*b_ptr++ = *a_ptr++;
*b_ptr = *a_ptr;
dev->device.curr_dte = 31250;
}
else if( fser )
GetFserSpeeds( dev );
else
{
WORD i;
LONG *a_ptr, *b_ptr;
if( tos<=0x104 )
i = *((WORD *)((BYTE *) dev->func_map->iorec + 34));
else
i = (WORD) Rsconf( -2, -1, -1, -1, -1, -1 );
a_ptr = speeds;
while( i )
{
i--;
a_ptr++;
}
dev->device.curr_dte = *a_ptr;
a_ptr = speeds;
b_ptr = dev->speeds;
while( *a_ptr>0 )
*b_ptr++ = *a_ptr++;
*b_ptr = *a_ptr;
}
return( TRUE );
}
/*-------------------------------------------------------------------*/
LOCAL VOID GetFcntlSpeeds( DEVICES *dev )
{
LONG *dte_ptr;
LONG last_dte, dte;
/*
* Aktuelle DTE-Speed retten:
*/
dev->device.curr_dte = -1;
Fcntl( dev->dhandle, &dev->device.curr_dte, TIOCIBAUD );
/*
* Von hohen zu niedrigen Baudraten wandern, solange es
* noch weitere gibt:
*/
dte_ptr = dev->speeds;
last_dte = dte = 0x7fffffffL;
while( TRUE )
{
Fcntl( dev->dhandle, &dte, TIOCIBAUD );
if( dte>=last_dte )
{
*dte_ptr = -1;
break;
}
else
last_dte = *dte_ptr++ = dte;
dte--;
}
/*
* DTE-Speed wiederherstellen:
*/
Fcntl( dev->dhandle, &dev->device.curr_dte, TIOCIBAUD );
return;
}
/*-------------------------------------------------------------------*/
LOCAL VOID GetFserSpeeds( DEVICES *dev )
{
BAUD_INFO *walk, *table;
WORD i, nums;
LONG *lptr;
table = (fser->baud_table_flag) ? dev->chan_info->alt_baud_table : dev->chan_info->baud_table;
nums = 0;
i = (WORD) Rsconf( -2, -1, -1, -1, -1, -1 );
walk = table;
while( i )
{
walk++;
i--;
}
dev->device.curr_dte = walk->baudrate;
walk = table;
while( walk->baudrate )
{
if( walk->baudrate>0 )
{
lptr = dev->speeds;
for( i=0; i<nums; i++ )
{
if( walk->baudrate>=*lptr )
break;
lptr++;
}
if( i<nums && !(walk->baudrate==*lptr) )
memcpy( lptr+1, lptr, (nums-i) * sizeof( LONG ) );
else if( i!=nums )
{
walk++;
continue;
}
*lptr = walk->baudrate;
nums++;
}
walk++;
}
dev->speeds[nums] = -1;
return;
}
/*-------------------------------------------------------------------*/
LOCAL VOID FreeSpeedlist( DEVICES *dev )
{
if( dev->speeds )
{
free( dev->speeds );
dev->speeds = NULL;
}
}
/*-------------------------------------------------------------------*/
LOCAL VOID SetDevFunctions( DEVICES *dev )
{
if( dev->dhandle>=0 )
Fcntl( dev->dhandle, dev->ioctrlmap, TIOCCTLMAP );
}
/*-------------------------------------------------------------------*/
LOCAL VOID SetPortProtokoll( DEVICES *dev )
{
UWORD flow=_RTSCTS;
if( dev->dhandle>=0 && !strcmp( dev->dopen, "MIDI" ) )
flow = _XONXOFF;
PortParameter( (DEV_LIST *) dev, flow, _8BIT, _1STOP, _NO_PARITY );
/*
* Unter MiNT muß noch der Terminal-Typ "raw" eingestellt
* werden (grrrrr!):
*/
if( dev->dhandle>=0 && !rsvf && MiNT )
{
SGTTYB tty;
if( !Fcntl( dev->dhandle, &tty, TIOCGETP ) )
{
tty.sg_flags = T_RAW;
Fcntl( dev->dhandle, &tty, TIOCSETP );
Fcntl( dev->dhandle, &tty, TIOCGETP );
}
}
}
/*-------------------------------------------------------------------*/
LOCAL BOOLEAN DevicePickup( DEVICES *dev )
{
LONG count;
dev->curr_pos = 0;
dev->num_read = -1;
if( (count=Fread( dev->dhandle, MAX_BLOCK, dev->buf ))<=0 )
return( FALSE );
dev->num_read = (WORD) count;
return( TRUE );
}
/*-------------------------------------------------------------------*/
LOCAL BOOLEAN DeviceSendBlock( DEVICES *dev, BYTE *block, LONG len, BOOLEAN tst_dcd )
{
LONG sent=0L, help;
LONG timeout=0;
while( sent<len )
{
if( tst_dcd && !IsCarrier( (DEV_LIST *) dev ) )
return( FALSE );
if( (help=Fwrite( dev->dhandle, len-sent, block+sent ))<0L )
return( FALSE );
sent += help;
if( sent<len )
{
if( !timeout )
timeout = Calc200Hz( 500L );
else
if( timeout<Get200Hz( ) )
break;
if( pause_1 )
pause_1( );
}
}
return( TRUE );
}